""""
createed: 2025-03-25 18:34:00
author: qinguoming
"""

import numpy as np
import re

def read_abaqus_inp(file_path):
    """
    读取Abaqus INP文件,解析节点、单元、Nset、Elset和Surface数据.

    参数:
        file_path (str): INP文件的路径.

    返回:
        nodes (numpy.ndarray): 节点数据,形状为 (n_nodes, 4),列分别为节点编号和坐标 (x, y, z).
        elements (numpy.ndarray): 单元数据,形状为 (n_elements, n_nodes_per_element + 1),列分别为单元编号和节点编号.
        nsets (dict): 节点集合数据,键为集合名称,值为包含节点编号的numpy数组.
        elsets (dict): 单元集合数据,键为集合名称,值为包含单元编号的numpy数组.
        surfaces (dict): Surface数据,键为Surface名称,值为包含(elem_label, elem_face_id)元组的列表.
    """
    nodes = []
    elements = []
    nsets = {}
    elsets = {}
    surfaces = {}
    current_section = None
    current_surface = None

    with open(file_path, 'r') as file:
        for line in file:
            line= re.sub(r'\s+', '',line)
            line = line.upper()
            if line.lower().startswith('*node'):
                current_section = 'Node'
                continue
            elif line.lower().startswith('*element'):
                current_section = 'Element'
                element_type = re.search(r'type=([a-zA-Z0-9_]+)', line)
                if element_type:
                    element_type = element_type.group(1)
                continue
            elif line.lower().startswith('*nset'):
                current_section = 'Nset'
                set_name = re.search(r'NSET=([a-zA-Z0-9_]+)', line).group(1)
                nsets[set_name] = []
                continue
            elif line.startswith('*ELSET'):
                current_section = 'Elset'
                set_name = re.search(r'ELSET=([a-zA-Z0-9_]+)', line).group(1)
                elsets[set_name] = []
                continue
            elif line.startswith('*SURFACE'):
                current_section = 'Surface'
                surface_name = re.search(r'NAME=([a-zA-Z0-9_]+)', line).group(1)
                surface_type = re.search(r'TYPE=([a-zA-Z0-9_]+)', line).group(1)
                surfaces[surface_name] = []
                current_surface = surface_name
                continue
            elif line.startswith('**'):
                current_section = None
                continue

            if current_section == 'Node':
                node_data = line.split(',')
                if len(node_data) > 1:  # 确保是有效数据行
                    node_id = int(node_data[0])
                    node_coords = [float(coord) for coord in node_data[1:]]
                    nodes.append([node_id] + node_coords)

            elif current_section == 'Element':
                element_data = line.split(',')
                if len(element_data) > 1:  # 确保是有效数据行
                    element_id = int(element_data[0])
                    element_nodes = [int(node) for node in element_data[1:]]
                    elements.append([element_id] + element_nodes)

            elif current_section == 'Nset':
                nset_data = line.split(',')
                nsets[set_name].extend([int(node) for node in nset_data if node])

            elif current_section == 'Elset':
                elset_data = line.split(',')
                elsets[set_name].extend([int(element) for element in elset_data if element])

            elif current_section == 'Surface':
                l1_el_set,l2_face_id= line.split(',')
                for e_idx in elsets[l1_el_set]:
                    # {surface_name: [(elem_label, elem_face_id),...],...}
                    surfaces[current_surface].append((int(e_idx), int(l2_face_id[-1])))        

    # 将节点和单元数据转换为numpy数组
    nodes = np.array(nodes, dtype=float)
    elements = np.array(elements, dtype=int)

    # 将Nset和Elset数据转换为numpy数组
    for set_name in nsets:
        nsets[set_name] = np.array(nsets[set_name], dtype=int)
    for set_name in elsets:
        elsets[set_name] = np.array(elsets[set_name], dtype=int)

    return nodes, elements, nsets, elsets, surfaces

# 示例用法
file_path = 'L:/EF2D/tests/data/surf_set_example3.inp'  # 替换为你的INP文件路径
nodes, elements, nsets, elsets, surfaces = read_abaqus_inp(file_path)

print("Nodes:")
print(nodes)
print("\nElements:")
print(elements)
print("\nNsets:")
print(nsets)
print("\nElsets:")
print(elsets)
print("\nSurfaces:")
for surface_name, surface_data in surfaces.items():
    print(f"{surface_name}: {surface_data}")
